#include "serializer/serializer.h"

#include <gtest/gtest.h>

#include <string>
#include <string_view>
#include <valarray>
#include <vector>

#ifdef __cpp_lib_span
#include <span>
#endif

using namespace serializer;

/**
 * 通用往返序列化工具函数
 * 参数:
 * - value 输入值
 * - options 序列化选项
 * 返回值: 反序列化结果
 * 异常: 序列化/反序列化失败时抛出异常
 */
template <typename T>
T
roundtrip_via_cpo(const T & value, const default_options & options)
{
    vector_writer writer;
    serialize(writer, value, options);
    vector_reader reader(writer.data());
    return deserialize_cpo(reader, options, type_tag<T>);
}

/**
 * 特化版本：string_view 序列化后反序列化为 string
 * 参数:
 * - value string_view 输入值
 * - options 序列化选项
 * 返回值: 反序列化得到的 string
 */
std::string
roundtrip_string_view_to_string(const std::string_view & value, const default_options & options)
{
    vector_writer writer;
    serialize(writer, value, options);
    vector_reader reader(writer.data());
    return deserialize_cpo(reader, options, type_tag<std::string>);
}

TEST(cpo_modern_containers_test, string_view_basic_roundtrip)
{
    default_options options{};

    // 基本字符串视图测试
    std::string original = "Hello, string_view world!";
    std::string_view sv(original);

    auto result = roundtrip_string_view_to_string(sv, options);
    EXPECT_EQ(result, original);
    EXPECT_EQ(result, std::string(sv));
}

TEST(cpo_modern_containers_test, string_view_empty_and_edge_cases)
{
    default_options options{};

    // 空字符串视图
    std::string_view empty_sv("");
    auto empty_result = roundtrip_string_view_to_string(empty_sv, options);
    EXPECT_TRUE(empty_result.empty());

    // 单字符
    std::string single_char = "x";
    std::string_view single_sv(single_char);
    auto single_result = roundtrip_string_view_to_string(single_sv, options);
    EXPECT_EQ(single_result, "x");

    // 包含特殊字符
    std::string special = "Hello\n\t\r\0World";
    std::string_view special_sv(special.data(), special.size());
    auto special_result = roundtrip_string_view_to_string(special_sv, options);
    EXPECT_EQ(special_result.size(), special.size());
    EXPECT_EQ(special_result, special);
}

TEST(cpo_modern_containers_test, string_view_substring_operations)
{
    default_options options{};

    // 测试字符串子串视图
    std::string full_string = "The quick brown fox jumps over the lazy dog";
    std::string_view substr_sv = std::string_view(full_string).substr(10, 10); // "brown fox "

    auto result = roundtrip_string_view_to_string(substr_sv, options);
    EXPECT_EQ(result, "brown fox ");
    EXPECT_EQ(result.size(), 10);
}

TEST(cpo_modern_containers_test, valarray_basic_roundtrip)
{
    default_options options{};

    // 基本数值数组测试
    std::valarray<int> va_int{1, 2, 3, 4, 5};
    auto result_int = roundtrip_via_cpo(va_int, options);

    EXPECT_EQ(result_int.size(), va_int.size());
    for (size_t i = 0; i < va_int.size(); ++i)
    {
        EXPECT_EQ(result_int[i], va_int[i]);
    }
}

TEST(cpo_modern_containers_test, valarray_different_types)
{
    default_options options{};

    // 浮点数数组
    std::valarray<double> va_double{1.1, 2.2, 3.3, 4.4};
    auto result_double = roundtrip_via_cpo(va_double, options);

    EXPECT_EQ(result_double.size(), va_double.size());
    for (size_t i = 0; i < va_double.size(); ++i)
    {
        EXPECT_DOUBLE_EQ(result_double[i], va_double[i]);
    }

    // 字符数组
    std::valarray<char> va_char{'a', 'b', 'c', 'd'};
    auto result_char = roundtrip_via_cpo(va_char, options);

    EXPECT_EQ(result_char.size(), va_char.size());
    for (size_t i = 0; i < va_char.size(); ++i)
    {
        EXPECT_EQ(result_char[i], va_char[i]);
    }
}

TEST(cpo_modern_containers_test, valarray_empty_and_large)
{
    default_options options{};

    // 空数组
    std::valarray<int> empty_va;
    auto empty_result = roundtrip_via_cpo(empty_va, options);
    EXPECT_EQ(empty_result.size(), 0);

    // 大数组
    std::valarray<int> large_va(1000);
    for (size_t i = 0; i < 1000; ++i)
    {
        large_va[i] = static_cast<int>(i * i);
    }

    auto large_result = roundtrip_via_cpo(large_va, options);
    EXPECT_EQ(large_result.size(), 1000);
    for (size_t i = 0; i < 1000; ++i)
    {
        EXPECT_EQ(large_result[i], static_cast<int>(i * i));
    }
}

TEST(cpo_modern_containers_test, valarray_mathematical_operations)
{
    default_options options{};

    // 测试经过数学运算的 valarray
    std::valarray<double> original{1.0, 2.0, 3.0, 4.0, 5.0};
    std::valarray<double> transformed = original * 2.0 + 1.0; // {3.0, 5.0, 7.0, 9.0, 11.0}

    auto result = roundtrip_via_cpo(transformed, options);

    EXPECT_EQ(result.size(), transformed.size());
    for (size_t i = 0; i < transformed.size(); ++i)
    {
        EXPECT_DOUBLE_EQ(result[i], transformed[i]);
        EXPECT_DOUBLE_EQ(result[i], original[i] * 2.0 + 1.0);
    }
}

#ifdef __cpp_lib_span
TEST(cpo_modern_containers_test, span_basic_roundtrip)
{
    default_options options{};

    // 基本 span 测试
    std::vector<int> vec{10, 20, 30, 40, 50};
    std::span<int> sp(vec);

    // span 序列化后反序列化为 vector
    vector_writer writer;
    serialize(writer, sp, options);
    vector_reader reader(writer.data());
    auto result = deserialize_cpo(reader, options, type_tag<std::vector<int>>);

    EXPECT_EQ(result.size(), sp.size());
    for (size_t i = 0; i < sp.size(); ++i)
    {
        EXPECT_EQ(result[i], sp[i]);
    }
}

TEST(cpo_modern_containers_test, span_subspan_operations)
{
    default_options options{};

    // 测试 span 的子范围
    std::vector<double> vec{1.1, 2.2, 3.3, 4.4, 5.5, 6.6};
    std::span<double> full_span(vec);
    std::span<double> sub_span = full_span.subspan(2, 3); // {3.3, 4.4, 5.5}

    vector_writer writer;
    serialize(writer, sub_span, options);
    vector_reader reader(writer.data());
    auto result = deserialize_cpo(reader, options, type_tag<std::vector<double>>);

    EXPECT_EQ(result.size(), 3);
    EXPECT_DOUBLE_EQ(result[0], 3.3);
    EXPECT_DOUBLE_EQ(result[1], 4.4);
    EXPECT_DOUBLE_EQ(result[2], 5.5);
}

TEST(cpo_modern_containers_test, span_const_and_dynamic)
{
    default_options options{};

    // 测试 const span
    const std::vector<int> const_vec{100, 200, 300};
    std::span<const int> const_span(const_vec);

    vector_writer writer;
    serialize(writer, const_span, options);
    vector_reader reader(writer.data());
    auto result = deserialize_cpo(reader, options, type_tag<std::vector<int>>);

    EXPECT_EQ(result.size(), const_span.size());
    for (size_t i = 0; i < const_span.size(); ++i)
    {
        EXPECT_EQ(result[i], const_span[i]);
    }

    // 测试动态大小 span
    int arr[] = {7, 8, 9, 10};
    std::span<int> dynamic_span(arr);

    vector_writer writer2;
    serialize(writer2, dynamic_span, options);
    vector_reader reader2(writer2.data());
    auto result2 = deserialize_cpo(reader2, options, type_tag<std::vector<int>>);

    EXPECT_EQ(result2.size(), 4);
    EXPECT_EQ(result2[0], 7);
    EXPECT_EQ(result2[1], 8);
    EXPECT_EQ(result2[2], 9);
    EXPECT_EQ(result2[3], 10);
}

TEST(cpo_modern_containers_test, span_empty)
{
    default_options options{};

    // 空 span
    std::vector<int> empty_vec;
    std::span<int> empty_span(empty_vec);

    vector_writer writer;
    serialize(writer, empty_span, options);
    vector_reader reader(writer.data());
    auto result = deserialize_cpo(reader, options, type_tag<std::vector<int>>);

    EXPECT_TRUE(result.empty());
    EXPECT_EQ(result.size(), 0);
}
#endif // __cpp_lib_span

TEST(cpo_modern_containers_test, mixed_modern_containers)
{
    default_options options{};

    // 测试现代容器的组合使用
    std::string base_string = "Modern C++ containers are powerful!";
    std::string_view sv(base_string);

    std::valarray<int> va{1, 2, 3, 4, 5};

    // 分别序列化
    auto sv_result = roundtrip_string_view_to_string(sv, options);
    auto va_result = roundtrip_via_cpo(va, options);

    EXPECT_EQ(sv_result, base_string);
    EXPECT_EQ(va_result.size(), va.size());
    for (size_t i = 0; i < va.size(); ++i)
    {
        EXPECT_EQ(va_result[i], va[i]);
    }
}